const path = require('path')
const EslintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 样式提取为单独文件，并进行压缩，用到两个插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
// 压缩图片
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
const CopyPlugin = require("copy-webpack-plugin");

const getStyleLoaders = (pre) => {
    return [
        MiniCssExtractPlugin.loader,
        'css-loader',
        {
            loader: 'postcss-loader',
            options: {
                postcssOptions: {
                    plugins: ['postcss-preset-env'],
                }
            }
        },
        pre,
    ].filter(Boolean)
}

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, '../dist'),   // 生产模式有路径
        filename: 'static/js/[name].[contenthash:10].js',     // 添加哈希值
        chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',     // 添加哈希值
        assetModuleFilename: 'static/media/[hash:10][ext][query]',
        clean: true, // 清空上一次打包内容
    },
    module: {
        rules: [
            {
                // 处理css
                test: /\.css$/,
                use: getStyleLoaders()
            },
            {
                // 处理less
                test: /\.less$/,
                use: getStyleLoaders('less-loader')
            },
            {
                // 处理sass
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader')
            },
            {
                // 处理stylus
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader')
            },
            {
                // 处理图片
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024,
                    }
                }
            },
            {
                // 处理其他资源
                test: /\.(woff2|ttf)$/,
                type: "asset/resource",
            },
            {
                // 处理js
                test: /\.jsx?$/,
                include: path.resolve(__dirname, '../src'),
                loader: 'babel-loader',
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            }
        ]
    },
    // 处理html
    plugins: [
        new EslintWebpackPlugin({
            context: path.resolve(__dirname, '../src'),
            exclude: 'node_modules',
            cache: true,
            cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache'),
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html')
        }),
        new MiniCssExtractPlugin({
            filename: 'static/css/[name].[contenthash:10].css',
            chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
        }),
        new CopyPlugin({
            patterns: [
                // 改为绝对路径，相对路径可能出问题
                {
                    from: path.resolve(__dirname, '../public'),
                    to: path.resolve(__dirname, '../dist'),
                    // 忽略index.html文件(因为上面HtmlWebpackPlugin已经有一份了)
                    globOptions: {
                        ignore: ["**/index.html"],
                    }
                },
            ],
        }),
    ],
    mode: 'production',
    devtool: 'source-map',
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
        runtimeChunk: {
            name: (entrypoint) => `runtime~${entrypoint.name}.js`,
        },
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerPlugin({
                minimizer: {
                    implementation: ImageMinimizerPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
    // 解析模块加载选项
    resolve: {
        // 自动补全文件拓展名
        extensions: [".jsx", ".js", ".json"]
    },

}